//
// Created by F1997 on 2025/4/9.
//

#include "shfe_decode.h"


// 解析数据包-shfe
void shfe_decode::parse_packet_shfe(const struct pcap_pkthdr* pkthdr, const u_char* packet, MarketData& marketData, std::ofstream &outFile) {
/*        std::cout << "解析数据包" << std::endl;
        // 输出原始数据包内容，以十六进制形式输出
        for (int i = 0; i < 20*//*pkthdr->caplen*//*; i++) {
            printf("%02x ", packet[i]);
            if ((i + 1) % 20 == 0) {
                printf("\n");
            }
        }
        printf("\n");*/

    // 解析以太网头部
    struct my_ether_header *eth_hdr = (struct my_ether_header *)packet;
    if (ntohs(eth_hdr->ether_type) == /*0*/0x0800) {
        // 解析IP头部
        struct my_ip_header *ip_hdr = (struct my_ip_header *)(packet + sizeof(struct my_ether_header));
        //printf("ip_v: %d\n", ip_hdr->ip_v);
        //printf("ip_src: %s\n", inet_ntoa(ip_hdr->ip_src));
        //printf("ip_dst: %s\n", inet_ntoa(ip_hdr->ip_dst));
        //printf("ip_p: %d\n", ip_hdr->ip_p);

        {
            // 过滤组播ip
            if (ip_hdr->ip_dst.s_addr == inet_addr(marketData.destinationIP.c_str()/*"239.3.41.71"*/)) {
                if (ip_hdr->ip_p == IPPROTO_TCP) {
                    // 解析TCP头部
                    struct my_tcp_header *tcp_hdr = (struct my_tcp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));

                    // 计算payload的起始位置
                    int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + (tcp_hdr->th_off * 4);
                    int payload_size = pkthdr->len - payload_offset;

/*                // 打印基本信息
                printf("Source IP: %s\n", inet_ntoa(ip_hdr->ip_src));
                printf("Destination IP: %s\n", inet_ntoa(ip_hdr->ip_dst));
                printf("Source Port: %d\n", ntohs(tcp_hdr->th_sport));
                printf("Destination Port: %d\n", ntohs(tcp_hdr->th_dport));
                printf("Payload Size: %d bytes\n", payload_size);

                // 打印payload
                if (payload_size > 0) {
                    printf("Payload:\n");
                    for (int i = 0; i < payload_size; ++i) {
                        printf("%02x ", packet[payload_offset + i]);
                        if ((i + 1) % 16 == 0) {
                            printf("\n");
                        }
                    }
                    printf("\n");
                }*/

                }
                else if (ip_hdr->ip_p == IPPROTO_UDP) {
                    struct my_udp_header *udp_hdr = (struct my_udp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));
                    // 计算payload的起始位置
                    int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + sizeof(struct my_udp_header); // udp包头长度固定为8？？？
                    int payload_size = pkthdr->len - payload_offset;
                    //printf("payload_size: %d\n", payload_size);
                    //printf("DstPort: %d\n", udp_hdr->DstPort);
                    if (payload_size > 25) {
                        // mirp报文头
                        struct MIRPHeader *mirpHeader = (struct MIRPHeader *)(packet + payload_offset);

                        //printf("DstPort: %d\n", udp_hdr->DstPort);
                        //printf("SrcPort: %d\n", udp_hdr->SrcPort);
                        //printf("len: %d\n", udp_hdr->len);
                        //printf("checkSum: %d\n", udp_hdr->checkSum);

                        //printf("payload_offset: %d\n", payload_offset);
                        //printf("payload_size: %d\n", payload_size);

                        //printf("mirpHeader->type_id: %d\n", mirpHeader->type_id);
                        //printf("%d\n", mirpHeader->center_change_no);
                        //printf("%d\n", mirpHeader->comm_phase_no); // 交易日
                        //printf("mirpHeader->snap_time: %d\n", mirpHeader->snap_time);
                        //printf("mirpHeader->snap_millisec: %d\n", mirpHeader->snap_millisec);
                        //printf("mirpHeader->packet_no: %d\n", mirpHeader->packet_no); // 唯一编号，有可能重复，表示多个包是同一个行情
                        //printf("=================================\n");

                        // 包内的数据提取到 MarketData
                        marketData.snap_time = mirpHeader->snap_time;
                        marketData.snap_millisec = mirpHeader->snap_millisec;
                        marketData.packet_no = mirpHeader->packet_no;

                        // 直接写入文件
                        outFile << mirpHeader->packet_no << ","
                                << pkthdr->ts.tv_sec << ","
                                << pkthdr->ts.tv_usec <<","
                                << std::endl;

                        // 进一步解析域串
                    }

                }

            }
        }

        // pcap 解析数据包
/*        if (ip_hdr->ip_p == IPPROTO_TCP) {
            // 解析TCP头部
            struct my_tcp_header *tcp_hdr = (struct my_tcp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));

            // 计算payload的起始位置
            int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + (tcp_hdr->th_off * 4);
            int payload_size = pkthdr->len - payload_offset;

*//*                // 打印基本信息
                printf("Source IP: %s\n", inet_ntoa(ip_hdr->ip_src));
                printf("Destination IP: %s\n", inet_ntoa(ip_hdr->ip_dst));
                printf("Source Port: %d\n", ntohs(tcp_hdr->th_sport));
                printf("Destination Port: %d\n", ntohs(tcp_hdr->th_dport));
                printf("Payload Size: %d bytes\n", payload_size);

                // 打印payload
                if (payload_size > 0) {
                    printf("Payload:\n");
                    for (int i = 0; i < payload_size; ++i) {
                        printf("%02x ", packet[payload_offset + i]);
                        if ((i + 1) % 16 == 0) {
                            printf("\n");
                        }
                    }
                    printf("\n");
                }*//*

        }
        else if (ip_hdr->ip_p == IPPROTO_UDP) {
            struct my_udp_header *udp_hdr = (struct my_udp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));
            // 计算payload的起始位置
            int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + sizeof(struct my_udp_header); // udp包头长度固定为8？？？
            int payload_size = pkthdr->len - payload_offset;
            printf("payload_size: %d\n", payload_size);
            printf("DstPort: %d\n", udp_hdr->DstPort);
            if (payload_size > 25) {
                // mirp报文头
                struct MIRPHeader *mirpHeader = (struct MIRPHeader *)(packet + payload_offset);

                printf("DstPort: %d\n", udp_hdr->DstPort);
                //printf("SrcPort: %d\n", udp_hdr->SrcPort);
                //printf("len: %d\n", udp_hdr->len);
                //printf("checkSum: %d\n", udp_hdr->checkSum);

                //printf("payload_offset: %d\n", payload_offset);
                //printf("payload_size: %d\n", payload_size);

                //printf("mirpHeader->type_id: %d\n", mirpHeader->type_id);
                //printf("%d\n", mirpHeader->center_change_no);
                //printf("%d\n", mirpHeader->comm_phase_no); // 交易日
                //printf("mirpHeader->snap_time: %d\n", mirpHeader->snap_time);
                //printf("mirpHeader->snap_millisec: %d\n", mirpHeader->snap_millisec);
                //printf("mirpHeader->packet_no: %d\n", mirpHeader->packet_no); // 唯一编号，有可能重复，表示多个包是同一个行情
                //printf("=================================\n");

                // 包内的数据提取到 MarketData
                marketData.snap_time = mirpHeader->snap_time;
                marketData.snap_millisec = mirpHeader->snap_millisec;
                marketData.packet_no = mirpHeader->packet_no;

                // 直接写入文件
                outFile << mirpHeader->packet_no << ","
                        << pkthdr->ts.tv_sec << ","
                        << pkthdr->ts.tv_usec <<","
                        << std::endl;

                // 进一步解析域串
            }

        }*/
    }
}
